use sea_orm::{Iden, ColumnTrait, EntityTrait, sea_query::{Expr, Func, Write, FunctionCall, SimpleExpr, IntoCondition, Alias}, IntoSimpleExpr, Condition};

use crate::utils::host::upload_url;
/* ------------------------------------------------------------ 格式化时间 ------------------------------------------------------------ */
// MySQL 格式化时间函数 => date_format( create_time, "%Y-%m-%d %H::%i::%s" )
struct DateFormat;
impl Iden for DateFormat { fn unquoted(&self, s: &mut dyn Write) { write!(s, "DATE_FORMAT").unwrap(); } }
pub fn date_format_all(expr:Expr, mode:usize, split:&str) -> FunctionCall{
    let vec = vec![
        format!("%Y{split}%m{split}%d"),
        format!("%Y{split}%m{split}%d %H:%i:%s"),
        format!("%Y{split}%m{split}%d %H:%i"),
        format!("%H:%i"),
        format!("%H:%i:%s"),
    ];
    Func::cust(DateFormat).arg(expr).arg(&vec[mode])
}
pub fn date_format_all_zone(expr:Expr, mode:usize, split:&str) -> FunctionCall{ 
    date_format_all(zone_expr_expr(expr), mode, split)
}

pub fn time_col_fn<C:ColumnTrait>(col:C, mode:usize) -> FunctionCall{ date_format_all_zone(col.into_expr(), mode, "-")}
pub fn time_col_expr<C:ColumnTrait>(col:C, mode:usize) -> Expr{ Expr::expr( time_col_fn(col, mode) )}
pub fn time_ec_expr<C:ColumnTrait, N:EntityTrait>(col:(N,C), mode:usize) -> Expr{ Expr::expr( date_format_all_zone(Expr::col(col), mode, "-") ) }
pub fn time_expr_fn(expr:Expr, mode:usize) -> FunctionCall{ date_format_all_zone(expr, mode, "-")}
pub fn time_expr_expr(expr:Expr, mode:usize) -> Expr{ Expr::expr( time_expr_fn(expr, mode) )}

pub fn datetime_col_fn<C:ColumnTrait>(col:C, mode:usize) -> FunctionCall{ date_format_all(col.into_expr(), mode, "-")}
pub fn datetime_col_expr<C:ColumnTrait>(col:C, mode:usize) -> Expr{ Expr::expr( datetime_col_fn(col, mode) )}
pub fn datetime_ec_expr<C:ColumnTrait, N:EntityTrait>(col:(N,C), mode:usize) -> Expr{ Expr::expr( date_format_all(Expr::col(col), mode, "-") ) }
/* ------------------------------------------------------------ 加时间 ------------------------------------------------------------ */
struct DateAdd;
impl Iden for DateAdd { fn unquoted(&self, s: &mut dyn Write) { write!(s, "DATE_ADD").unwrap(); } }
pub fn date_add_col_fn(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(DateAdd).args(args) }
pub fn date_add_col_expr<C>(col:C, num:u32, i:usize) -> Expr where C:ColumnTrait {
    let vec = vec![ "year", "month", "day", "hour", "minute", "second" ];
    return Expr::expr(date_add_col_fn(vec![
        col.into_simple_expr(),
        keyword_exprs(&format!("INTERVAL {} {}", num, vec[i]))
    ]));
}
/* ------------------------------------------------------------ 对比时间 ------------------------------------------------------------ */
struct Date;
impl Iden for Date { fn unquoted(&self, s: &mut dyn Write) { write!(s, "DATE").unwrap(); } }
pub fn date_col_fn<C>(col:C) -> FunctionCall where C:ColumnTrait { Func::cust(Date).arg(zone(col.into_expr())) }
pub fn date_col_expr<C>(col:C) -> Expr where C:ColumnTrait { Expr::expr(date_col_fn(col)) }
struct Timestamp;
impl Iden for Timestamp { fn unquoted(&self, s: &mut dyn Write) { write!(s, "TIMESTAMP").unwrap(); } }
pub fn timestamp_col_fn<C:ColumnTrait>(col:C) -> FunctionCall { Func::cust(Timestamp).arg(zone(col.into_expr())) }
pub fn timestamp_col_expr<C:ColumnTrait>(col:C) -> Expr { Expr::expr( timestamp_col_fn(col) )}
/* ------------------------------------------------------------ 对比时间 ------------------------------------------------------------ */
/* ------------------------------------------------------------ 时区转换，转为北京时间 ------------------------------------------------------------ */
struct ConvertTz;
impl Iden for ConvertTz { fn unquoted(&self, s: &mut dyn Write) { write!(s, "CONVERT_TZ").unwrap(); } }
pub fn zone(expr:Expr) -> FunctionCall{ Func::cust(ConvertTz).arg(expr.into_simple_expr()).arg(Expr::value("+00:00")).arg(Expr::value("+08:00"))}
pub fn zone_expr_expr(expr:Expr) -> Expr { Expr::expr(zone(expr)) }
/* ------------------------------------------------------------ 组合字段 ------------------------------------------------------------ */
struct Concat;
impl Iden for Concat { fn unquoted(&self, s: &mut dyn Write) { write!(s, "CONCAT").unwrap(); } }
pub fn concat(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(Concat).args(args) }
pub fn concat_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr(concat(args)) }
pub fn concat_exprs(args:Vec<SimpleExpr>) -> SimpleExpr{ concat_expr(args).into_simple_expr() }
pub fn upload_url_col_fn<C:ColumnTrait>(col:C) -> FunctionCall{ concat(vec![ upload_url().into(), col.into_simple_expr()])}
pub fn upload_url_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr(upload_url_col_fn(col)) }
struct ConcatWs;
impl Iden for ConcatWs { fn unquoted(&self, s: &mut dyn Write) { write!(s, "CONCAT_WS").unwrap(); } }
pub fn concat_ws(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(ConcatWs).args(args) }
pub fn concat_ws_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr(concat_ws(args)) }
/* ------------------------------------------------------------ 数据转换 ------------------------------------------------------------ */
struct Convert;
impl Iden for Convert { fn unquoted(&self, s: &mut dyn Write) { write!(s, "CONVERT").unwrap(); } }
pub fn convert(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(Convert).args(args)}
pub fn convert_str_expr<C:ColumnTrait>(col:C) -> Expr { Expr::expr(convert(vec![col.into_simple_expr(),Expr::custom_keyword(Alias::new("CHAR")).into()]))}
/* ------------------------------------------------------------ 截取字符串 ------------------------------------------------------------ */
struct Substr;
impl Iden for Substr { fn unquoted(&self, s: &mut dyn Write) { write!(s, "SUBSTR").unwrap(); } }
pub fn substr(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(Substr).args(args)}
/* ------------------------------------------------------------ 流程判断 ------------------------------------------------------------ */
struct Ter;
impl Iden for Ter { fn unquoted(&self, s: &mut dyn Write) { write!(s, "IF").unwrap(); } }
pub fn ter(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(Ter).args(args)}
pub fn ter_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr( ter(args) ) }
pub fn ter_exprs(args:Vec<SimpleExpr>) -> SimpleExpr{ ter_expr(args).into_simple_expr() }
pub fn ter_null_col_expr<C1:ColumnTrait,C2:ColumnTrait,C3:ColumnTrait>(col1:C1, col2:C2, col3:C3) -> Expr{
    ter_expr(vec![ col1.is_not_null().into_simple_expr(), col2.into_simple_expr(), col3.into_simple_expr() ])
}
pub fn ter_num_col_expr<C:ColumnTrait>(col:C ) -> Expr{ ter_expr(vec![ col.into_simple_expr(), 1.into(), 0.into() ]) }
struct Ifnull;
impl Iden for Ifnull { fn unquoted(&self, s: &mut dyn Write) { write!(s, "IFNULL").unwrap(); } }
pub fn if_null(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(Ifnull).args(args)}
pub fn if_null_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr( if_null(args) ) }
struct Isnull;
impl Iden for Isnull { fn unquoted(&self, s: &mut dyn Write) { write!(s, "ISNULL").unwrap(); } }
pub fn is_null(arg:SimpleExpr) -> FunctionCall{ Func::cust(Isnull).arg(arg) }
pub fn is_null_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr( is_null(col.into_simple_expr() ) ) }
/* ------------------------------------------------------------ 分组查询 ------------------------------------------------------------ */
struct GroupConcat;
impl Iden for GroupConcat { fn unquoted(&self, s: &mut dyn Write) { write!(s, "GROUP_CONCAT").unwrap(); } }
pub fn group_concat(arg:SimpleExpr) -> FunctionCall { Func::cust(GroupConcat).arg(arg) }
pub fn group_concat_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr(group_concat(col.into_simple_expr()) ) }
pub fn group_concat_expr_expr(expr:Expr) -> Expr{ Expr::expr(group_concat(expr.into_simple_expr()) ) }
pub fn group_concat_arr_col_expr<C:ColumnTrait>(col:C) -> Expr{ json_arr_col_expr(col) }
/* ------------------------------------------------------------ 查询数据转为 json 数组对象 ------------------------------------------------------------ */
struct JsonArray;
impl Iden for JsonArray { fn unquoted(&self, s: &mut dyn Write) { write!(s, "JSON_ARRAY").unwrap(); } }
pub fn json_array(arg:SimpleExpr) -> FunctionCall { Func::cust(JsonArray).arg(arg) }
pub fn json_arr_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr(json_array(col.into_simple_expr())) }
pub fn json_arr_expr_expr(expr:Expr) -> Expr{ Expr::expr(json_array(expr.into_simple_expr())) }
pub fn json_arr_group_col_expr<C:ColumnTrait>(col:C) -> Expr{ json_arr_expr_expr(group_concat_col_expr(col)) }
/* ------------------------------------------------------------ 查询数据转为 json 数组对象 ------------------------------------------------------------ */
struct JsonArrayAgg;
impl Iden for JsonArrayAgg { fn unquoted(&self, s: &mut dyn Write) { write!(s, "JSON_ARRAYAGG").unwrap(); } }
pub fn json_arrayagg(func:FunctionCall) -> FunctionCall { Func::cust(JsonArrayAgg).arg(func) }
// pub fn json_arrayagg_fn_expr(func:FunctionCall) -> Expr{ Expr::expr( json_arrayagg(func) ) }

pub fn json_arr_obj(args:Vec<SimpleExpr>) -> FunctionCall{ json_arrayagg(json_object(args)) }
pub fn json_arr_obj_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr(json_arr_obj(args)) }

pub fn json_arr_obj_ter<C:ColumnTrait>(col:C, args:Vec<SimpleExpr>) -> FunctionCall { ter(vec![ 
        col.is_not_null().into_simple_expr(), 
        json_arr_obj(args).into(), 
        Expr::custom_keyword(Alias::new("NULL")).into()
    ]) 
}
pub fn json_arr_obj_ter_expr<C:ColumnTrait>(col:C, args:Vec<SimpleExpr>) -> Expr { Expr::expr( json_arr_obj_ter(col,args) ) }
struct JsonObject;
impl Iden for JsonObject { fn unquoted(&self, s: &mut dyn Write) { write!(s, "JSON_OBJECT").unwrap(); } }
pub fn json_object(args:Vec<SimpleExpr>) -> FunctionCall{Func::cust(JsonObject).args(args)}
pub fn json_object_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr(json_object(args)) }
struct Replace;
impl Iden for Replace { fn unquoted(&self, s: &mut dyn Write) { write!(s, "REPLACE").unwrap(); } }
pub fn replace() -> FunctionCall{Func::cust(Replace)}
pub fn json_arr_to_str_col_expr<C:ColumnTrait>(col:C) -> Expr{ // 将 json 转为逗号分隔的字符串 [1,2] => 1,2
    Expr::expr(
        replace().args(vec![
            replace().args(vec![
                replace().args(vec![
                    replace().args(
                        vec![ col.into_simple_expr(),"[".into(),"".into() ]
                    ).into(),
                    "]".into(),
                    "".into()
                ]).into(),
                " ".into(),
                "".into()
            ]).into(),
            "\"".into(),
            "".into()
        ])
    )
}
pub fn json_arr_to_str_expr_expr(expr:SimpleExpr) -> Expr{ // 将 json 转为逗号分隔的字符串 [1,2] => 1,2
    Expr::expr(
        replace().args(vec![
            replace().args(vec![
                replace().args(vec![
                    replace().args(
                        vec![ expr,"[".into(),"".into() ]
                    ).into(),
                    "]".into(),
                    "".into()
                ]).into(),
                " ".into(),
                "".into()
            ]).into(),
            "\"".into(),
            "".into()
        ])
    )
}
/* ------------------------------------------------------------ 查询 json 数组对象中每条数据的某个字段集合，返回 [1,2] ------------------------------------------------------------ */
struct JsonExtract;
impl Iden for JsonExtract { fn unquoted(&self, s: &mut dyn Write) { write!(s, "JSON_EXTRACT").unwrap(); } }
pub fn json_extract(args:Vec<SimpleExpr>) -> FunctionCall{Func::cust(JsonExtract).args(args)}
pub fn json_extract_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr(json_extract(args)) }
pub fn json_extract_exprs(args:Vec<SimpleExpr>) -> SimpleExpr{ json_extract_expr(args).into_simple_expr() }

// find_in_set(id,'1,2') => [{ id:1 }]
pub fn in_json_arr_str<C1:ColumnTrait, C2:ColumnTrait>(col_id:C1, col_json:C2, name:&str) -> Condition{
    let arr = json_extract_expr(vec![ col_json.into_simple_expr(), format!("$[*].{}", name).into() ]).into_simple_expr();
    Expr::expr(Func::cust(FindInset).arg(col_id.into_expr()).arg(json_arr_to_str_expr_expr(arr))).into_simple_expr().into_condition()
}
struct FindInset;
impl Iden for FindInset { fn unquoted(&self, s: &mut dyn Write) { write!(s, "FIND_IN_SET").unwrap(); } }
pub fn find_in_set<C1:ColumnTrait, C2:ColumnTrait>(id:C1, str:C2) -> FunctionCall{Func::cust(FindInset).arg(id.into_expr()).arg(str.into_expr())}
pub fn find_in_set_exprs<C1:ColumnTrait, C2:ColumnTrait>(id:C1, str:C2) -> SimpleExpr{ Expr::expr( find_in_set(id, str) ).into_simple_expr() }
// find_in_set(id,'1,2')
pub fn find_in_set_str<C1:ColumnTrait, C2:ColumnTrait>(id:C1, str:C2) -> Condition{ find_in_set_exprs(id,str).into_condition() }
// find_in_set(id,'1,2') => [1,2] => 1,2
pub fn find_in_set_arr_str<C1:ColumnTrait, C2:ColumnTrait>(id:C1, json:C2) -> Condition{Expr::expr( Func::cust(FindInset).arg(id.into_expr()).arg(json_arr_to_str_col_expr(json)) ).into_simple_expr().into_condition()}
// * ------------------------------------------------------------ 去掉小数后的 0 ------------------------------------------------------------ */
struct Format;
impl Iden for Format { fn unquoted(&self, s: &mut dyn Write) { write!(s, "FORMAT").unwrap(); } }
pub fn format(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(Format).args(args) }
pub fn format_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr( format(args) ) }
pub fn format_exprs_expr(exprs:SimpleExpr) -> Expr{ format_expr(vec![exprs.into(), 0.into()]) }

// 转为 money，保留两位小数
pub fn money_col_expr<C:ColumnTrait>(col:C) -> Expr{ format_expr(vec![col.into_simple_expr(), 2.into()]) }
pub fn money_col_exprs<C:ColumnTrait>(col:C) -> SimpleExpr{ money_col_expr(col).into_simple_expr() }
pub fn money_exprs_expr(exprs:SimpleExpr) -> Expr{ format_expr(vec![exprs.into(), 2.into()]) }
pub fn money_exprs_exprs(exprs:SimpleExpr) -> SimpleExpr{ money_exprs_expr(exprs).into_simple_expr() }
pub fn money_expr_expr(expr:Expr) -> Expr{ format_expr(vec![expr.into_simple_expr(), 2.into()]) }
pub fn money_fn_expr(col:FunctionCall) -> Expr{ format_expr(vec![col.into(), 2.into()]) }
// * ------------------------------------------------------------ 生成 UUID------------------------------------------------------------ */
struct Uuid;
impl Iden for Uuid { fn unquoted(&self, s: &mut dyn Write) { write!(s, "UUID").unwrap(); } }
pub fn uuid() -> FunctionCall{ Func::cust(Uuid) }
pub fn uuid_expr() -> Expr{ Expr::expr( uuid() ) }
// * ------------------------------------------------------------ 将小数转为百分比 ------------------------------------------------------------ */
pub fn percent_col_expr<C:ColumnTrait>(col:C) -> Expr{ concat_expr(vec![ col.into_simple_expr(),"%".into() ]) }
// * ------------------------------------------------------------ 转换数据类型 ------------------------------------------------------------ */
struct Cast;
impl Iden for Cast { fn unquoted(&self, s: &mut dyn Write) { write!(s, "CAST").unwrap(); } }
pub fn cast(arg:&str) -> FunctionCall{ Func::cust(Cast).arg(arg) }
pub fn cast_expr(arg:&str) -> Expr{ Expr::expr(cast(arg)) }
// * ------------------------------------------------------------ 去除前缀，01 取 1 ------------------------------------------------------------ */
pub fn zero_start_num<C:ColumnTrait>(col:C) -> Expr {
    Expr::expr(
        Expr::case(
            col.like("0_"),
            Expr::value(substr(vec![ col.into_simple_expr(), 2.into() ]))
        ).finally(
            col.into_expr()
        )
    )
}
pub fn zero_start_num_expr<C:ColumnTrait>(col:C) -> SimpleExpr { zero_start_num(col).into_simple_expr() }
// * ------------------------------------------------------------ 去除小数后多余 0 ------------------------------------------------------------ */
pub fn zero_exprs_exprs(exprs:SimpleExpr) -> SimpleExpr{ Expr::expr(Func::cast_as(exprs, Alias::new("CHAR"))).add(0)}
pub fn zero_exprs_expr(exprs:SimpleExpr) -> Expr{ Expr::expr(zero_exprs_exprs(exprs.into_simple_expr())) }
pub fn zero_col_exprs<C:ColumnTrait>(col:C) -> SimpleExpr{ zero_exprs_exprs(col.into_simple_expr()) }
pub fn zero_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr(zero_col_exprs(col)) }
// * ------------------------------------------------------------ 取最大值 ------------------------------------------------------------ */
pub fn max_col_fn<C:ColumnTrait>(col:C) -> FunctionCall{ Func::max(col.into_expr()) }
pub fn max_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr( max_col_fn(col) ) }

pub fn min_col_fn<C:ColumnTrait>(col:C) -> FunctionCall{ Func::min(col.into_expr()) }
pub fn min_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr( min_col_fn(col) ) }

pub fn sum_exprs_fn(exprs:SimpleExpr) -> FunctionCall{ Func::sum(exprs) }
pub fn sum_exprs_exprs(exprs:SimpleExpr) -> SimpleExpr{ Expr::expr(Func::sum(exprs)).into_simple_expr() }
pub fn sum_col_fn<C:ColumnTrait>(col:C) -> FunctionCall{ Func::sum(col.into_expr()) }
pub fn sum_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr( sum_col_fn(col) ) }
pub fn sum_col_exprs<C:ColumnTrait>(col:C) -> SimpleExpr{ Expr::expr( sum_col_fn(col) ).into_simple_expr() }
// pub fn sum_expr_expr(expr:Expr) -> Expr{ Expr::expr( Func::sum(expr) ) }
// * ------------------------------------------------------------ 将数字转成 SQL 值 ------------------------------------------------------------ */
pub fn expr_num(num:i32) -> Expr { Expr::val(num) }
// * ------------------------------------------------------------ 关键字 ------------------------------------------------------------ */
pub fn alias(key:&str) -> Alias { Alias::new(key) }
pub fn keyword_expr(key:&str) -> Expr { Expr::custom_keyword(alias(key)).into() }
pub fn keyword_exprs(key:&str) -> SimpleExpr { keyword_expr(key).into_simple_expr() }
// * ------------------------------------------------------------ 计算时间差值 ------------------------------------------------------------ */
struct TimeDiff;
impl Iden for TimeDiff { fn unquoted(&self, s: &mut dyn Write) { write!(s, "TIMESTAMPDIFF").unwrap(); } }
pub fn time_diff(args:Vec<SimpleExpr>) -> FunctionCall{ Func::cust(TimeDiff).args(args) }
pub fn time_diff_expr(args:Vec<SimpleExpr>) -> Expr{ Expr::expr(Func::cust(TimeDiff).args(args)) }
// 两个时间的差值
pub fn time_diff_two_month_col_expr<C:ColumnTrait>(start:C, end:C) -> Expr{ time_diff_expr(vec![ 
    Expr::custom_keyword(Alias::new("month")).into(), start.into_simple_expr(), end.into_simple_expr(), ])
}
pub fn time_diff_two_month_col_exprs<C:ColumnTrait>(start:C, end:C) -> SimpleExpr{ time_diff_two_month_col_expr(start, end).into_simple_expr() }
pub fn time_diff_two_day_col_expr<C:ColumnTrait>(start:C, end:C) -> Expr{ time_diff_expr(vec![ 
    Expr::custom_keyword(Alias::new("day")).into(), start.into_simple_expr(), end.into_simple_expr(), ]) 
}
pub fn time_diff_two_day_col_exprs<C:ColumnTrait>(start:C, end:C) -> SimpleExpr{ time_diff_two_day_col_expr(start, end).into_simple_expr() }
// pub fn time_diff_two_month_col_exprs<C:ColumnTrait>(start:C, end:C) -> SimpleExpr{ time_diff_two_month_col_expr(start, end).into_simple_expr() }
// 未来时间到现在时间的天差值
pub fn time_diff_day_col<C:ColumnTrait>(col:C) -> Expr{ time_diff_expr(vec![ 
    Expr::custom_keyword(Alias::new("day")).into(), Expr::custom_keyword(Alias::new("now()")).into(), col.into_simple_expr() ])
}
pub fn time_diff_day_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr(time_diff_day_col(col).add(1)) }
pub fn time_diff_day_col_exprs<C:ColumnTrait>(col:C) -> SimpleExpr{ time_diff_day_col(col).add(1).into_simple_expr() }
// 未来时间到现在时间的月差值
pub fn time_diff_month_col_expr<C:ColumnTrait>(col:C) -> Expr{ time_diff_expr(vec![ 
   Expr::custom_keyword(Alias::new("month")).into(), Expr::custom_keyword(Alias::new("now()")).into(),  col.into_simple_expr() ]) 
}
pub fn time_diff_month_col_exprs<C:ColumnTrait>(col:C) -> SimpleExpr{ time_diff_month_col_expr(col).into_simple_expr() }
// 未来时间到现在时间的秒值
pub fn time_diff_second_col<C:ColumnTrait>(col:C) -> Expr{ time_diff_expr(vec![ 
    Expr::custom_keyword(Alias::new("second")).into(), Expr::custom_keyword(Alias::new("now()")).into(), col.into_simple_expr() ])
}
pub fn time_diff_second_col_exprs<C:ColumnTrait>(col:C) -> SimpleExpr{ time_diff_second_col(col).into_simple_expr() }
pub fn time_diff_second_expr_expr(expr:Expr) -> Expr{ time_diff_expr(vec![ 
    Expr::custom_keyword(Alias::new("second")).into(), Expr::custom_keyword(Alias::new("now()")).into(), expr.into_simple_expr() ])
}
pub fn time_diff_second_expr_exprs(expr:Expr) -> SimpleExpr{ time_diff_second_expr_expr(expr).into_simple_expr() }
// // * ------------------------------------------------------------ 返回最大数 ------------------------------------------------------------ */
// struct Floor;
// impl Iden for Floor { fn unquoted(&self, s: &mut dyn Write) { write!(s, "FLOOR").unwrap(); } }
// pub fn floor(arg:Expr) -> FunctionCall{ Func::cust(Floor).arg(arg) }
// pub fn floor_expr(arg:Expr) -> Expr{ Expr::expr(Func::cust(Floor).arg(arg)) }
// pub fn floor_exprs(arg:Expr) -> SimpleExpr{ floor_expr(arg).into_simple_expr() }
// // * ------------------------------------------------------------ 最多保留两位小数 ------------------------------------------------------------ */
struct Truncate;
impl Iden for Truncate { fn unquoted(&self, s: &mut dyn Write) { write!(s, "TRUNCATE").unwrap(); } }
pub fn truncate_col_expr<C:ColumnTrait>(col:C) -> Expr{ Expr::expr(Func::cust(Truncate).arg(col.into_expr()).arg(2)) }
pub fn truncate_exprs_expr(arg:SimpleExpr) -> Expr{ Expr::expr(Func::cust(Truncate).arg(arg).arg(2)) }